﻿#ifndef ZFTPPRIVATE_H
#define ZFTPPRIVATE_H

/******************************************************************************
** ZFtp私有实现类
**
*******************************************************************************/

#include <QObject>
#include <QSharedPointer>
#include <QQueue>
#include <QMutex>
#include <QPointer>
#include "qftp.h"
#include "ZFtp.h"
#include "ZFtpConfig.h"

BEGIN_NAMESPACE_ZFTPNS

class ZFtpPrivate : public QObject
{
    Q_OBJECT
    Q_DECLARE_PUBLIC_D(q_ptr.data(), ZFtp)

public:
    explicit ZFtpPrivate(QObject *parent = NULL);
    ~ZFtpPrivate();

    /**
     * @brief setFtpServerTextCodec
     *  设置服务器的编码，防止中文乱码
     * @param text_codec_name
     */
    void setFtpServerTextCodec(const QString &text_codec_name);

    /**
     * @brief ftpServerTextCodec
     *  获取Ftp编码格式
     * @return
     */
    QString ftpServerTextCodec();

    /**
     * @brief setAutoReconnect
     */
    void setAutoReconnect(bool reconnect);

    /**
     * @brief autoReconnect
     * @return
     */
    bool autoReconnect();

    /**
     * @brief connectToHost
     *  连接服务器
     * @param request
     * @param response
     */
    void connectToHost(QSharedPointer<ConnectToHostRequestPrivate> request, QSharedPointer<ConnectToHostResponsePrivate> response);

    /**
     * @brief login
     *  登录Ftp服务器
     * @param request
     * @param response
     */
    void login(QSharedPointer<LoginRequestPrivate> request, QSharedPointer<LoginResponsePrivate> response);

    /**
     * @brief close
     *  关闭Ftp连接
     * @param request
     * @param response
     */
    void close(QSharedPointer<CloseFtpRequestPrivate> request, QSharedPointer<CloseFtpResponsePrivate> response);

    /**
     * @brief listDir
     *  列出目录
     * @param request
     * @param response
     */
    void listDir(QSharedPointer<ListDirRequestPrivate> request, QSharedPointer<ListDirResponsePrivate> response);

    /**
     * @brief mkdir
     *  创建目录
     * @param request
     * @param response
     */
    void mkdir(QSharedPointer<MkDirRequestPrivate> request, QSharedPointer<MkDirResponsePrivate> response);

    /**
     * @brief rmdir
     *  删除目录
     * @param request
     * @param response
     */
    void rmdir(QSharedPointer<RmDirRequestPrivate> request, QSharedPointer<RmDirResponsePrivate> response);

    /**
     * @brief cd
     *  进入目录
     * @param request
     * @param response
     */
    void cd(QSharedPointer<CdDirRequestPrivate> request, QSharedPointer<CdDirResponsePrivate> response);

    /**
     * @brief uploadFile
     *  上传1
     * @param request
     * @param response
     */
    void uploadFile(QSharedPointer<UploadFileRequest1Private> request, QSharedPointer<UploadFileResponse1Private> response);

    /**
     * @brief uploadFile
     *  上传2
     * @param request
     * @param response
     */
    void uploadFile(QSharedPointer<UploadFileRequest2Private> request, QSharedPointer<UploadFileResponse2Private> response);

    /**
     * @brief uploadFile
     *  上传3
     * @param request
     * @param response
     */
    void uploadFile(QSharedPointer<UploadFileRequest3Private> request, QSharedPointer<UploadFileResponse3Private> response);

    /**
     * @brief downloadFile
     *  下载V1
     * @param request
     * @param response
     */
    void downloadFile(QSharedPointer<DownloadFileRequest1Private> request, QSharedPointer<DownloadFileResponse1Private> response);

    /**
     * @brief downloadFile
     *  下载V1
     * @param request
     * @param response
     */
    void downloadFile(QSharedPointer<DownloadFileRequest2Private> request, QSharedPointer<DownloadFileResponse2Private> response);

    /**
     * @brief deleteFile
     *  删除文件
     * @param request
     * @param response
     */
    void deleteFile(QSharedPointer<DeleteFileRequestPrivate> request, QSharedPointer<DeleteFileResponsePrivate> response);

    /**
     * @brief renameFile
     *  重命名文件
     * @param request
     * @param response
     */
    void renameFile(QSharedPointer<RenameFileRequestPrivate> request, QSharedPointer<RenameFileResponsePrivate> response);

    /**
     * @brief setTransferMode
     *  设置传输模式
     * @param mode
     */
    void setTransferMode(QFtp::TransferMode mode);

    /**
     * @brief state
     * @return
     */
    QFtp::State state() const;

    /**
     * @brief error
     * @return
     */
    QFtp::Error	error() const;

    /**
     * @brief errorString
     * @return
     */
    QString	errorString() const;

public slots:
    void abort();

private:
    QSharedPointer<QFtp> m_ftp;
    QPointer<ZFtp> q_ptr;

    // 自己维护命令队列，不使用QFtp的命令队列
    struct RequestTask
    {
        QSharedPointer<ZFtpRequestPrivate> request;
        QSharedPointer<ZFtpResponsePrivate> response;
    };

    // 请求的任务队列
    QList<RequestTask> m_request_task_list;

    // 请求任务队列锁
    QMutex m_task_list_mutex;

    // 保存当前正在执行的Ftp任务
    RequestTask m_current_ftp_task;

    // Ftp配置对象
    QSharedPointer<ZFtpConfig> m_zftp_config;

private:
    void init();
    void createConnects();

    /**
     * @brief applyFtpObject
     */
    void applyFtpObject(QSharedPointer<QFtp>);

    /**
     * @brief ensureFtpObjectValid
     *  保证QFtp对象存在
     */
    void ensureFtpObjectValid();

    /**
     * @brief tryStartNewTask
     *  尝试开始新任务
     */
    void tryStartNextTask();

    /**
     * @brief addTask
     */
    void addTask(QSharedPointer<ZFtpRequestPrivate>, QSharedPointer<ZFtpResponsePrivate>);

    /**
     * @brief isFtpBusy
     * @return
     */
    bool isFtpBusy();

private slots:
    void slotCommandFinished(int id, bool error);
    void slotCommandStarted(int id);
    void slotDataTransferProgress(qint64 done, qint64 total);
    void slotListInfo(const QUrlInfo &i);
    void slotFtpStateChanged(int state);
    void slotNewTaskAdded(QSharedPointer<ZFtpRequestPrivate>, QSharedPointer<ZFtpResponsePrivate>);

signals:
    void sigFtpStateChanged(int state);
    void sigNewTaskAdded(QSharedPointer<ZFtpRequestPrivate>, QSharedPointer<ZFtpResponsePrivate>);
};

END_NAMESPACE


#endif // ZFTPPRIVATE_H
